/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.wdullaer.materialdatetimepicker.time;

import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.global.resource.ResourceManager;

import com.wdullaer.materialdatetimepicker.ResourceTable;
import com.wdullaer.materialdatetimepicker.Utils;
import com.wdullaer.materialdatetimepicker.common.Log;
import com.wdullaer.materialdatetimepicker.common.ResourceUtils;

import java.text.DateFormatSymbols;
import java.util.Locale;

/**
 * Draw the two smaller AM and PM circles next to where the larger circle will be.
 */
public class AmPmCirclesView extends Component implements Component.DrawTask {
    private static final String TAG = "AmPmCirclesView";

    // Alpha level for selected circle.
    private static final int SELECTED_ALPHA = Utils.SELECTED_ALPHA;
    private static final int SELECTED_ALPHA_THEME_DARK = Utils.SELECTED_ALPHA_THEME_DARK;

    private final Paint mPaint = new Paint();
    private int mSelectedAlpha;
    private int mTouchedColor;
    private int mUnselectedColor;
    private int mAmPmTextColor;
    private int mAmPmSelectedTextColor;
    private int mAmPmDisabledTextColor;
    private int mSelectedColor;
    private float mCircleRadiusMultiplier;
    private float mAmPmCircleRadiusMultiplier;
    private String mAmText;
    private String mPmText;
    private boolean mAmDisabled;
    private boolean mPmDisabled;
    private boolean mIsInitialized;

    private static final int AM = TimePickerDialog.AM;
    private static final int PM = TimePickerDialog.PM;

    private boolean mDrawValuesReady;
    private int mAmPmCircleRadius;
    private int mAmXCenter;
    private int mPmXCenter;
    private int mAmPmYCenter;
    private int mAmOrPm;
    private int mAmOrPmPressed;

    public AmPmCirclesView(Context context) {
        super(context);
        mIsInitialized = false;
    }

    public void initialize(TimePickerDialog.Type type, Context context, Font font, Locale locale, TimePickerController controller, int amOrPm) {
        if (mIsInitialized) {
            Log.e(TAG, "AmPmCirclesView may only be initialized once.");
            return;
        }

        ResourceManager res = context.getResourceManager();

        if (controller.isThemeDark()) {
            mUnselectedColor = ResourceUtils.getColorValue(res, ResourceTable.Color_mdtp_circle_background_dark_theme);
            mAmPmTextColor = ResourceUtils.getColorValue(res, ResourceTable.Color_mdtp_white);
            mAmPmDisabledTextColor = ResourceUtils.getColorValue(res, ResourceTable.Color_mdtp_date_picker_text_disabled_dark_theme);
            mSelectedAlpha = SELECTED_ALPHA_THEME_DARK;
        } else {
            mUnselectedColor = ResourceUtils.getColorValue(res, ResourceTable.Color_mdtp_white);
            mAmPmTextColor = ResourceUtils.getColorValue(res, ResourceTable.Color_mdtp_ampm_text_color);
            mAmPmDisabledTextColor = ResourceUtils.getColorValue(res, ResourceTable.Color_mdtp_date_picker_text_disabled);
            mSelectedAlpha = SELECTED_ALPHA;
        }

        mSelectedColor = controller.getAccentColor();
        mTouchedColor = Utils.darkenColor(mSelectedColor);
        mAmPmSelectedTextColor = ResourceUtils.getColorValue(res, ResourceTable.Color_mdtp_white);

        if (font != null) {
            mPaint.setFont(font);
        } else { // TODO 待处理
        }
        mPaint.setAntiAlias(true);
        mPaint.setTextAlign(TextAlignment.CENTER);

        mCircleRadiusMultiplier = ResourceUtils.getFloat(res, ResourceTable.Float_mdtp_circle_radius_multiplier);
        mAmPmCircleRadiusMultiplier = ResourceUtils.getFloat(res, ResourceTable.Float_mdtp_ampm_circle_radius_multiplier);
        String[] amPmTexts = new DateFormatSymbols(locale).getAmPmStrings();
        switch (type) {
            case JALALI:
                mAmText = "ق.ظ";
                mPmText = "ب.ظ";
                break;
            default:
                mAmText = amPmTexts[0];
                mPmText = amPmTexts[1];
                break;
        }

        mAmDisabled = controller.isAmDisabled();
        mPmDisabled = controller.isPmDisabled();

        setAmOrPm(amOrPm);
        mAmOrPmPressed = -1;

        mIsInitialized = true;
        addDrawTask(this);
    }

    public boolean isInitialized() {
        return mIsInitialized;
    }

    public void setAmOrPm(int amOrPm) {
        mAmOrPm = amOrPm;
    }

    public void setAmOrPmPressed(int amOrPmPressed) {
        mAmOrPmPressed = amOrPmPressed;
    }

    /**
     * Calculate whether the coordinates are touching the AM or PM circle.
     *
     * @param xCoord x coord
     * @param yCoord y coord
     * @return int
     */
    public int getIsTouchingAmOrPm(float xCoord, float yCoord) {
        Utils.log("AmPmCirclesView getIsTouchingAmOrPm: x:" + xCoord + ", y:" + yCoord);
        if (!mDrawValuesReady) {
            return -1;
        }

        int squaredYDistance = (int) ((yCoord - mAmPmYCenter) * (yCoord - mAmPmYCenter));
        Utils.log("AmPmCirclesView getIsTouchingAmOrPm squaredYDistance: " + squaredYDistance);

        int distanceToAmCenter =
            (int) Math.sqrt((xCoord - mAmXCenter) * (xCoord - mAmXCenter) + squaredYDistance);
        Utils.log("AmPmCirclesView getIsTouchingAmOrPm distanceToAmCenter: " + distanceToAmCenter);
        if (distanceToAmCenter <= mAmPmCircleRadius && !mAmDisabled) {
            return AM;
        }

        int distanceToPmCenter =
            (int) Math.sqrt((xCoord - mPmXCenter) * (xCoord - mPmXCenter) + squaredYDistance);
        Utils.log("AmPmCirclesView getIsTouchingAmOrPm distanceToPmCenter" + distanceToPmCenter);
        if (distanceToPmCenter <= mAmPmCircleRadius && !mPmDisabled) {
            return PM;
        }

        // Neither was close enough.
        return -1;
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        int viewWidth = getWidth();
        if (viewWidth == 0 || !mIsInitialized) {
            return;
        }

        if (!mDrawValuesReady) {
            int layoutXCenter = getWidth() / 2;
            int layoutYCenter = getHeight() / 2;
            int circleRadius =
                (int) (Math.min(layoutXCenter, layoutYCenter) * mCircleRadiusMultiplier);
            mAmPmCircleRadius = (int) (circleRadius * mAmPmCircleRadiusMultiplier);
            layoutYCenter += mAmPmCircleRadius * 0.75;
            int textSize = mAmPmCircleRadius * 3 / 4;
            mPaint.setTextSize(textSize);

            // Line up the vertical center of the AM/PM circles with the bottom of the main circle.
            mAmPmYCenter = layoutYCenter - mAmPmCircleRadius / 2 + circleRadius;
            // Line up the horizontal edges of the AM/PM circles with the horizontal edges
            // of the main circle.
            mAmXCenter = layoutXCenter - circleRadius + mAmPmCircleRadius;
            mPmXCenter = layoutXCenter + circleRadius - mAmPmCircleRadius;
//          Utils.log("layoutXCenter:"+layoutXCenter+", circleRadius:"+circleRadius+", mAmPmCircleRadius:"+mAmPmCircleRadius);

            mDrawValuesReady = true;
        }

        // We'll need to draw either a lighter blue (for selection), a darker blue (for touching)
        // or white (for not selected).
        int amColor = mUnselectedColor;
        int amAlpha = 255;
        int amTextColor = mAmPmTextColor;
        int pmColor = mUnselectedColor;
        int pmAlpha = 255;
        int pmTextColor = mAmPmTextColor;

        if (mAmOrPm == AM) {
            amColor = mSelectedColor;
            amAlpha = mSelectedAlpha;
            amTextColor = mAmPmSelectedTextColor;
        } else if (mAmOrPm == PM) {
            pmColor = mSelectedColor;
            pmAlpha = mSelectedAlpha;
            pmTextColor = mAmPmSelectedTextColor;
        }
        if (mAmOrPmPressed == AM) {
            amColor = mTouchedColor;
            amAlpha = mSelectedAlpha;
        } else if (mAmOrPmPressed == PM) {
            pmColor = mTouchedColor;
            pmAlpha = mSelectedAlpha;
        }
        if (mAmDisabled) {
            amColor = mUnselectedColor;
            amTextColor = mAmPmDisabledTextColor;
        }
        if (mPmDisabled) {
            pmColor = mUnselectedColor;
            pmTextColor = mAmPmDisabledTextColor;
        }

        // Draw the two circles.
        mPaint.setColor(new Color(amColor));
        mPaint.setAlpha(amAlpha / 255f);
        canvas.drawCircle(mAmXCenter, mAmPmYCenter, mAmPmCircleRadius, mPaint);
        mPaint.setColor(new Color(pmColor));
        mPaint.setAlpha(pmAlpha / 255f);
        canvas.drawCircle(mPmXCenter, mAmPmYCenter, mAmPmCircleRadius, mPaint);

        // Draw the AM/PM texts on top.
        mPaint.setColor(new Color(amTextColor));
        int textYCenter = mAmPmYCenter - (int) (mPaint.descent() + mPaint.ascent()) / 2;
        canvas.drawText(mPaint, mAmText, mAmXCenter, textYCenter);
        mPaint.setColor(new Color(pmTextColor));
        canvas.drawText(mPaint, mPmText, mPmXCenter, textYCenter);
    }
}
